New file containing the abstracted keyboard driver. Most code taken from
authorAlexander Larsson <alla@lysator.liu.se>
Fri, 8 Dec 2000 12:38:48 +0000 (12:38 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Fri, 8 Dec 2000 12:38:48 +0000 (12:38 +0000)
2000-12-08  Alexander Larsson  <alla@lysator.liu.se>

* gdk/linux-fb/gdkkeyboard-fb.c:
New file containing the abstracted keyboard driver. Most code
taken from gdkinput-ps2.c

* gdk/linux-fb/gdkinput-ps2.c:
Removed file.

* gdk/linux-fb/Makefile.am:
Added gdkkeyboard-fb.c, removed gdkinput-ps2.c.

* gdk/linux-fb/gdkcolor-fb.c:
display->fb was renamed to display->fb_fd.

* gdk/linux-fb/gdkcursor-fb.c:
gdk_mouse_get_info -> gdk_fb_mouse_get_info

* gdk/linux-fb/gdkinput.c:
Moved gdk_input_init here from gdkinput-ps2.c

* gdk/linux-fb/gdkmain-fb.c:
display->fb was renamed to display->fb_fd.
Now the tty and the console is opened here instead
of in the keyboard driver. Also check GDK_VT to see what
tty to open.
Move gdk_beep () here from gdkinput-ps2.c
gdk_mouse_get_info -> gdk_fb_mouse_get_info

* gdk/linux-fb/gdkmouse-fb.c:
Add header.
gdk_mouse_get_info -> gdk_fb_mouse_get_info
Return correct keyboard modifiers.
GDK_MOUSETYPE -> GDK_MOUSE_TYPE for consistancy

* gdk/linux-fb/gdkprivate-fb.h:
Add tty and vt info to display.
Add orignal modeinfo storage to display
Update global functions

* gdk/linux-fb/gdkwindow-fb.c:
Added gdk_fb_window_find_focus().
gdk_mouse_get_info -> gdk_fb_mouse_get_info

17 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/linux-fb/Makefile.am
gdk/linux-fb/gdkcolor-fb.c
gdk/linux-fb/gdkcursor-fb.c
gdk/linux-fb/gdkinput-ps2.c [deleted file]
gdk/linux-fb/gdkinput.c
gdk/linux-fb/gdkkeyboard-fb.c [new file with mode: 0644]
gdk/linux-fb/gdkmain-fb.c
gdk/linux-fb/gdkmouse-fb.c
gdk/linux-fb/gdkprivate-fb.h
gdk/linux-fb/gdkwindow-fb.c

index f8706bf8b41856346d5dc04d82904fd9073dd0f2..6c34dac089c9f98d9961d4ae966b4ffc930b0b50 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+2000-12-08  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkkeyboard-fb.c:
+       New file containing the abstracted keyboard driver. Most code
+       taken from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed file.
+       
+       * gdk/linux-fb/Makefile.am:
+       Added gdkkeyboard-fb.c, removed gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkcolor-fb.c:
+       display->fb was renamed to display->fb_fd.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkinput.c:
+       Moved gdk_input_init here from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       display->fb was renamed to display->fb_fd.
+       Now the tty and the console is opened here instead
+       of in the keyboard driver. Also check GDK_VT to see what
+       tty to open.
+       Move gdk_beep () here from gdkinput-ps2.c
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkmouse-fb.c:
+       Add header.
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+       Return correct keyboard modifiers.
+       GDK_MOUSETYPE -> GDK_MOUSE_TYPE for consistancy
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add tty and vt info to display.
+       Add orignal modeinfo storage to display
+       Update global functions
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Added gdk_fb_window_find_focus().
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
 2000-12-07  Havoc Pennington  <hp@pobox.com>
 
        * gdk/x11/gdkkeys-x11.c (gdk_keymap_lookup_key): fix name of 
index f8706bf8b41856346d5dc04d82904fd9073dd0f2..6c34dac089c9f98d9961d4ae966b4ffc930b0b50 100644 (file)
@@ -1,3 +1,47 @@
+2000-12-08  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkkeyboard-fb.c:
+       New file containing the abstracted keyboard driver. Most code
+       taken from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed file.
+       
+       * gdk/linux-fb/Makefile.am:
+       Added gdkkeyboard-fb.c, removed gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkcolor-fb.c:
+       display->fb was renamed to display->fb_fd.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkinput.c:
+       Moved gdk_input_init here from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       display->fb was renamed to display->fb_fd.
+       Now the tty and the console is opened here instead
+       of in the keyboard driver. Also check GDK_VT to see what
+       tty to open.
+       Move gdk_beep () here from gdkinput-ps2.c
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkmouse-fb.c:
+       Add header.
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+       Return correct keyboard modifiers.
+       GDK_MOUSETYPE -> GDK_MOUSE_TYPE for consistancy
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add tty and vt info to display.
+       Add orignal modeinfo storage to display
+       Update global functions
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Added gdk_fb_window_find_focus().
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
 2000-12-07  Havoc Pennington  <hp@pobox.com>
 
        * gdk/x11/gdkkeys-x11.c (gdk_keymap_lookup_key): fix name of 
index f8706bf8b41856346d5dc04d82904fd9073dd0f2..6c34dac089c9f98d9961d4ae966b4ffc930b0b50 100644 (file)
@@ -1,3 +1,47 @@
+2000-12-08  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkkeyboard-fb.c:
+       New file containing the abstracted keyboard driver. Most code
+       taken from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed file.
+       
+       * gdk/linux-fb/Makefile.am:
+       Added gdkkeyboard-fb.c, removed gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkcolor-fb.c:
+       display->fb was renamed to display->fb_fd.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkinput.c:
+       Moved gdk_input_init here from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       display->fb was renamed to display->fb_fd.
+       Now the tty and the console is opened here instead
+       of in the keyboard driver. Also check GDK_VT to see what
+       tty to open.
+       Move gdk_beep () here from gdkinput-ps2.c
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkmouse-fb.c:
+       Add header.
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+       Return correct keyboard modifiers.
+       GDK_MOUSETYPE -> GDK_MOUSE_TYPE for consistancy
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add tty and vt info to display.
+       Add orignal modeinfo storage to display
+       Update global functions
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Added gdk_fb_window_find_focus().
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
 2000-12-07  Havoc Pennington  <hp@pobox.com>
 
        * gdk/x11/gdkkeys-x11.c (gdk_keymap_lookup_key): fix name of 
index f8706bf8b41856346d5dc04d82904fd9073dd0f2..6c34dac089c9f98d9961d4ae966b4ffc930b0b50 100644 (file)
@@ -1,3 +1,47 @@
+2000-12-08  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkkeyboard-fb.c:
+       New file containing the abstracted keyboard driver. Most code
+       taken from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed file.
+       
+       * gdk/linux-fb/Makefile.am:
+       Added gdkkeyboard-fb.c, removed gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkcolor-fb.c:
+       display->fb was renamed to display->fb_fd.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkinput.c:
+       Moved gdk_input_init here from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       display->fb was renamed to display->fb_fd.
+       Now the tty and the console is opened here instead
+       of in the keyboard driver. Also check GDK_VT to see what
+       tty to open.
+       Move gdk_beep () here from gdkinput-ps2.c
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkmouse-fb.c:
+       Add header.
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+       Return correct keyboard modifiers.
+       GDK_MOUSETYPE -> GDK_MOUSE_TYPE for consistancy
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add tty and vt info to display.
+       Add orignal modeinfo storage to display
+       Update global functions
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Added gdk_fb_window_find_focus().
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
 2000-12-07  Havoc Pennington  <hp@pobox.com>
 
        * gdk/x11/gdkkeys-x11.c (gdk_keymap_lookup_key): fix name of 
index f8706bf8b41856346d5dc04d82904fd9073dd0f2..6c34dac089c9f98d9961d4ae966b4ffc930b0b50 100644 (file)
@@ -1,3 +1,47 @@
+2000-12-08  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkkeyboard-fb.c:
+       New file containing the abstracted keyboard driver. Most code
+       taken from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed file.
+       
+       * gdk/linux-fb/Makefile.am:
+       Added gdkkeyboard-fb.c, removed gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkcolor-fb.c:
+       display->fb was renamed to display->fb_fd.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkinput.c:
+       Moved gdk_input_init here from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       display->fb was renamed to display->fb_fd.
+       Now the tty and the console is opened here instead
+       of in the keyboard driver. Also check GDK_VT to see what
+       tty to open.
+       Move gdk_beep () here from gdkinput-ps2.c
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkmouse-fb.c:
+       Add header.
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+       Return correct keyboard modifiers.
+       GDK_MOUSETYPE -> GDK_MOUSE_TYPE for consistancy
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add tty and vt info to display.
+       Add orignal modeinfo storage to display
+       Update global functions
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Added gdk_fb_window_find_focus().
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
 2000-12-07  Havoc Pennington  <hp@pobox.com>
 
        * gdk/x11/gdkkeys-x11.c (gdk_keymap_lookup_key): fix name of 
index f8706bf8b41856346d5dc04d82904fd9073dd0f2..6c34dac089c9f98d9961d4ae966b4ffc930b0b50 100644 (file)
@@ -1,3 +1,47 @@
+2000-12-08  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkkeyboard-fb.c:
+       New file containing the abstracted keyboard driver. Most code
+       taken from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed file.
+       
+       * gdk/linux-fb/Makefile.am:
+       Added gdkkeyboard-fb.c, removed gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkcolor-fb.c:
+       display->fb was renamed to display->fb_fd.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkinput.c:
+       Moved gdk_input_init here from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       display->fb was renamed to display->fb_fd.
+       Now the tty and the console is opened here instead
+       of in the keyboard driver. Also check GDK_VT to see what
+       tty to open.
+       Move gdk_beep () here from gdkinput-ps2.c
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkmouse-fb.c:
+       Add header.
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+       Return correct keyboard modifiers.
+       GDK_MOUSETYPE -> GDK_MOUSE_TYPE for consistancy
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add tty and vt info to display.
+       Add orignal modeinfo storage to display
+       Update global functions
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Added gdk_fb_window_find_focus().
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
 2000-12-07  Havoc Pennington  <hp@pobox.com>
 
        * gdk/x11/gdkkeys-x11.c (gdk_keymap_lookup_key): fix name of 
index f8706bf8b41856346d5dc04d82904fd9073dd0f2..6c34dac089c9f98d9961d4ae966b4ffc930b0b50 100644 (file)
@@ -1,3 +1,47 @@
+2000-12-08  Alexander Larsson  <alla@lysator.liu.se>
+
+       * gdk/linux-fb/gdkkeyboard-fb.c:
+       New file containing the abstracted keyboard driver. Most code
+       taken from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed file.
+       
+       * gdk/linux-fb/Makefile.am:
+       Added gdkkeyboard-fb.c, removed gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkcolor-fb.c:
+       display->fb was renamed to display->fb_fd.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkinput.c:
+       Moved gdk_input_init here from gdkinput-ps2.c
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       display->fb was renamed to display->fb_fd.
+       Now the tty and the console is opened here instead
+       of in the keyboard driver. Also check GDK_VT to see what
+       tty to open.
+       Move gdk_beep () here from gdkinput-ps2.c
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
+       * gdk/linux-fb/gdkmouse-fb.c:
+       Add header.
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+       Return correct keyboard modifiers.
+       GDK_MOUSETYPE -> GDK_MOUSE_TYPE for consistancy
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Add tty and vt info to display.
+       Add orignal modeinfo storage to display
+       Update global functions
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Added gdk_fb_window_find_focus().
+       gdk_mouse_get_info -> gdk_fb_mouse_get_info
+
 2000-12-07  Havoc Pennington  <hp@pobox.com>
 
        * gdk/x11/gdkkeys-x11.c (gdk_keymap_lookup_key): fix name of 
index 0fcdf7f0a900df868cc6a10d283cf4beb943dee0..0f56977204910efaae3be4cd20456f121552c6ad 100644 (file)
@@ -49,7 +49,7 @@ libgdk_linux_fb_la_SOURCES =    \
        gdkwindow-fb.c          \
        gdkprivate-fb.h         \
        gdkinputprivate.h       \
-       gdkinput-ps2.c          \
+       gdkkeyboard-fb.c        \
        gdkmouse-fb.c           \
        gdkevents-fb.c          \
        gdkrender-fb.c          \
index 6a11d4bb49f0517c2747813b8018ab98a36fc654..ed32cd9ce3627779575be4b4df312fe564ca736b 100644 (file)
@@ -155,7 +155,7 @@ gdk_colormap_new (GdkVisual *visual,
          fbc.green = green;
          fbc.blue = blue;
 
-         if (ioctl (fbd->fd, FBIOGETCMAP, &fbc))
+         if (ioctl (fbd->fb_fd, FBIOGETCMAP, &fbc))
            g_error("ioctl(FBIOGETCMAP) failed");
 
          for (i = 0; i < colormap->size; i++)
@@ -351,7 +351,7 @@ gdk_colormap_change (GdkColormap *colormap,
             colormap->colors[i].green +
             colormap->colors[i].blue)/3;
        }
-      ioctl (gdk_display->fd, FBIOPUTCMAP, &fbc);
+      ioctl (gdk_display->fb_fd, FBIOPUTCMAP, &fbc);
       break;
 
     case GDK_VISUAL_PSEUDO_COLOR:
@@ -361,7 +361,7 @@ gdk_colormap_change (GdkColormap *colormap,
          green[i] = colormap->colors[i].green;
          blue[i] = colormap->colors[i].blue;
        }
-      ioctl (gdk_display->fd, FBIOPUTCMAP, &fbc);
+      ioctl (gdk_display->fb_fd, FBIOPUTCMAP, &fbc);
       break;
 
     default:
@@ -565,7 +565,7 @@ gdk_colormap_alloc1 (GdkColormap *colormap,
          fbc.green = &green;
          fbc.blue = &blue;
 
-         ioctl (gdk_display->fd, FBIOPUTCMAP, &fbc);
+         ioctl (gdk_display->fb_fd, FBIOPUTCMAP, &fbc);
 
          ret->pixel = i;
          colormap->colors[ret->pixel] = *ret;
@@ -785,7 +785,7 @@ gdk_color_change (GdkColormap *colormap,
       fbc.red = &color->red;
       fbc.green = &color->green;
       fbc.blue = &color->blue;
-      ioctl (gdk_display->fd, FBIOPUTCMAP, &fbc);
+      ioctl (gdk_display->fb_fd, FBIOPUTCMAP, &fbc);
       break;
 
     default:
index 6dab9f8bd6ab3446e86305666b98aaf04c1983b5..9aefc0abda78a1b8910898c9ec3ee6a08a1a9494 100644 (file)
@@ -517,6 +517,6 @@ gdk_fb_cursor_reset(void)
   GdkWindow *win = gdk_window_at_pointer (NULL, NULL);
   gint x, y;
 
-  gdk_mouse_get_info (&x, &y, NULL);
+  gdk_fb_mouse_get_info (&x, &y, NULL);
   gdk_fb_cursor_move (x, y, win);
 }
diff --git a/gdk/linux-fb/gdkinput-ps2.c b/gdk/linux-fb/gdkinput-ps2.c
deleted file mode 100644 (file)
index 2eccb61..0000000
+++ /dev/null
@@ -1,781 +0,0 @@
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <gdk/gdk.h>
-#include <gdk/gdkinternals.h>
-#include "gdkinputprivate.h"
-#include "gdkkeysyms.h"
-#include "gdkprivate-fb.h"
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <time.h>
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <sys/vt.h>
-#include <sys/time.h>
-#include <sys/kd.h>
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <linux/fb.h>
-
-/* Two minutes */
-#define BLANKING_TIMEOUT 120*1000
-
-/*
- * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
- * file for a list of people on the GTK+ Team.  See the ChangeLog
- * files for a list of changes.  These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
- */
-
-typedef struct {
-  gint fd, fd_tag, consfd;
-
-  int vtnum, prev_vtnum;
-  guint modifier_state;
-  gboolean caps_lock : 1;
-} Keyboard;
-
-static guint blanking_timer = 0;
-
-static Keyboard * tty_keyboard_open(void);
-
-static Keyboard *keyboard = NULL;
-
-#ifndef VESA_NO_BLANKING
-#define VESA_NO_BLANKING        0
-#define VESA_VSYNC_SUSPEND      1
-#define VESA_HSYNC_SUSPEND      2
-#define VESA_POWERDOWN          3
-#endif
-
-#if 0
-static gboolean
-input_activity_timeout(gpointer p)
-{
-  blanking_timer = 0;
-  ioctl(gdk_display->fd, FBIOBLANK, VESA_POWERDOWN);
-  return FALSE;
-}
-#endif
-
-/* This is all very broken :( */
-static void
-input_activity (void)
-{
-#if 0
-  if (blanking_timer)
-    g_source_remove (blanking_timer);
-  else
-    gdk_fb_redraw_all ();
-
-  blanking_timer = g_timeout_add (BLANKING_TIMEOUT, input_activity_timeout, NULL);
-#endif
-}
-
-void
-gdk_input_init (void)
-{
-  gdk_input_devices = g_list_append (NULL, gdk_core_pointer);
-
-  gdk_input_ignore_core = FALSE;
-
-  gdk_fb_mouse_open ();
-}
-
-GdkWindow *
-gdk_window_find_focus (void)
-{
-  if (_gdk_fb_keyboard_grab_window)
-    return _gdk_fb_keyboard_grab_window;
-  else if (GDK_WINDOW_P (gdk_parent_root)->children)
-    {
-      GList *item;
-      for (item = GDK_WINDOW_P (gdk_parent_root)->children; item; item = item->next)
-       {
-         GdkWindowObject *priv = item->data;
-
-         if (priv->mapped)
-           return item->data;
-       }
-    }
-
-  return gdk_parent_root;
-}
-
-/* Bogus implementation */
-gboolean
-gdk_keymap_get_entries_for_keycode (GdkKeymap     *keymap,
-                                    guint          hardware_keycode,
-                                    GdkKeymapKey **keys,
-                                    guint        **keyvals,
-                                    gint          *n_entries)
-{
-  return FALSE;
-}
-
-static const guint trans_table[256][3] = {
-  /* 0x00 */
-  {0, 0, 0},
-  {GDK_Escape, 0, 0},
-  {'1', '!', 0},
-  {'2', '@', 0},
-  {'3', '#', 0},
-  {'4', '$', 0},
-  {'5', '%', 0},
-  {'6', '^', 0},
-  {'7', '&', 0},
-  {'8', '*', 0},
-  {'9', '(', 0},
-  {'0', ')', 0},
-  {'-', '_', 0},
-  {'=', '+', 0},
-  {GDK_BackSpace, 0, 0},
-  {GDK_Tab, 0, 0},
-
-  /* 0x10 */
-  {'q', 'Q', 0},
-  {'w', 'W', 0},
-  {'e', 'E', 0},
-  {'r', 'R', 0},
-  {'t', 'T', 0},
-  {'y', 'Y', 0},
-  {'u', 'U', 0},
-  {'i', 'I', 0},
-  {'o', 'O', 0},
-  {'p', 'P', 0},
-  {'[', '{', 0},
-  {']', '}', 0},
-  {GDK_Return, 0, 0},
-  {GDK_Control_L, 0, 0}, /* mod */
-  {'a', 'A', 0},
-  {'s', 'S', 0},
-
-       /* 0x20 */
-  {'d', 'D', 0},
-  {'f', 'F', 0},
-  {'g', 'G', 0},
-  {'h', 'H', 0},
-  {'j', 'J', 0},
-  {'k', 'K', 0},
-  {'l', 'L', 0},
-  {';', ':', 0},
-  {'\'', '"', 0},
-  {'`', '~', 0},
-  {GDK_Shift_L, 0, 0}, /* mod */
-  {'\\', 0, 0},
-  {'z', 0, 0},
-  {'x', 0, 0},
-  {'c', 0, 0},
-
-  {'v', 'V', 0},
-
-       /* 0x30 */
-  {'b', 'B', 0},
-  {'n', 'N', 0},
-  {'m', 'M', 0},
-  {',', 0, 0},
-  {'.', 0, 0},
-  {'/', 0, 0},
-  {GDK_Shift_R, 0, 0}, /* mod */
-  {GDK_KP_Multiply, 0, 0},
-  {0, 0, 0},
-  {GDK_space, 0, 0},
-  {0, 0, 0},
-  {GDK_F1, 0, 0},
-  {GDK_F2, 0, 0},
-  {GDK_F3, 0, 0},
-  {GDK_F4, 0, 0},
-  {GDK_F5, 0, 0},
-
-       /* 0x40 */
-  {GDK_F6, 0, 0},
-  {GDK_F7, 0, 0},
-  {GDK_F8, 0, 0},
-  {GDK_F9, 0, 0},
-  {GDK_F10, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {'7', 0, 0},
-  {'8', 0, 0},
-  {'9', 0, 0},
-  {'-', 0, 0},
-  {'4', 0, 0},
-  {'5', 0, 0},
-  {'6', 0, 0},
-  {'+', 0, 0},
-  {'1', 0, 0},
-
-       /* 0x50 */
-  {'2', 0, 0},
-  {'3', 0, 0},
-  {'0', 0, 0},
-  {'.', 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {GDK_F11, 0, 0},
-  {GDK_F12, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0x60 */
-  {GDK_Return, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0x70 */
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0x80 */
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0x90 */
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0xA0 */
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0xB0 */
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0xC0 */
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {GDK_Up, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {GDK_Left, 0, 0},
-  {0, 0, 0},
-  {GDK_Right, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0xD0 */
-  {GDK_Down, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0xE0 */
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-
-       /* 0xF0 */
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-  {0, 0, 0},
-};
-
-#define TRANS_TABLE_SIZE (sizeof(trans_table)/sizeof(trans_table[0]))
-
-static gboolean
-handle_mediumraw_keyboard_input (GIOChannel *gioc,
-                                GIOCondition cond,
-                                gpointer data)
-{
-  guchar buf[128];
-  int i, n;
-  Keyboard *k = data;
-  guint32 now;
-
-  n = read (k->fd, buf, sizeof(buf));
-  if (n <= 0)
-    g_error("Nothing from keyboard!");
-
-  /* Now turn this into a keyboard event */
-  now = gdk_fb_get_time ();
-
-  for (i = 0; i < n; i++)
-    {
-      guchar keycode;
-      gboolean key_up;
-      GdkEvent *event;
-      GdkWindow *win;
-      char dummy[2];
-      int mod;
-      guint keyval;
-
-      keycode = buf[i] & 0x7F;
-      key_up = buf[i] & 0x80;
-
-      if (keycode > TRANS_TABLE_SIZE)
-       {
-         g_warning ("Unknown keycode\n");
-         continue;
-       }
-
-      if ( (keycode == 0x1D) /* left Ctrl */
-          || (keycode == 0x9D) /* right Ctrl */
-          || (keycode == 0x38) /* left Alt */
-          || (keycode == 0xB8) /* right Alt */
-          || (keycode == 0x2A) /* left Shift */
-          || (keycode == 0x36) /* right Shift */)
-       {
-         switch (keycode)
-           {
-           case 0x1D: /* Left Ctrl */
-           case 0x9D: /* Right Ctrl */
-             if (key_up)
-               k->modifier_state &= ~GDK_CONTROL_MASK;
-             else
-               k->modifier_state |= GDK_CONTROL_MASK;
-             break;
-           case 0x38: /* Left Alt */
-           case 0xB8: /* Right Alt */
-             if (key_up)
-               k->modifier_state &= ~GDK_MOD1_MASK;
-             else
-               k->modifier_state |= GDK_MOD1_MASK;
-             break;
-           case 0x2A: /* Left Shift */
-           case 0x36: /* Right Shift */
-             if (key_up)
-               k->modifier_state &= ~GDK_SHIFT_MASK;
-             else
-               k->modifier_state |= GDK_SHIFT_MASK;
-             break;
-           }
-         continue; /* Don't generate events for modifiers */
-       }
-
-      if (keycode == 0x3A /* Caps lock */)
-       {
-         if (!key_up)
-           k->caps_lock = !k->caps_lock;
-         
-         ioctl (k->fd, KDSETLED, k->caps_lock ? LED_CAP : 0);
-         continue;
-       }
-
-      if (trans_table[keycode][0] >= GDK_F1 &&
-         trans_table[keycode][0] <= GDK_F35 &&
-         (k->modifier_state & GDK_MOD1_MASK))
-       {
-         if (key_up) /* Only switch on release */
-           {
-             gint vtnum = trans_table[keycode][0] - GDK_F1 + 1;
-
-             /* Do the whole funky VT switch thing */
-             ioctl (k->consfd, VT_ACTIVATE, vtnum);
-             ioctl (k->consfd, VT_WAITACTIVE, k->vtnum);
-             gdk_fb_redraw_all ();
-           }
-
-         continue;
-       }
-
-      keyval = 0;
-      mod = 0;
-      if (k->modifier_state & GDK_CONTROL_MASK)
-       mod = 2;
-      else if (k->modifier_state & GDK_SHIFT_MASK)
-       mod = 1;
-      do {
-       keyval = trans_table[keycode][mod--];
-      } while (!keyval && (mod >= 0));
-
-      if (k->caps_lock && (keyval >= 'a') && (keyval <= 'z'))
-       keyval = toupper (keyval);
-
-      /* handle some magic keys */
-      if (k->modifier_state & (GDK_CONTROL_MASK|GDK_MOD1_MASK))
-       {
-         if (key_up)
-           {
-             if (keyval == GDK_BackSpace)
-               exit (1);
-
-             if (keyval == GDK_Return)
-               gdk_fb_redraw_all ();
-           }
-
-         keyval = 0;
-       }
-
-      if (!keyval)
-       continue;
-
-      win = gdk_window_find_focus ();
-      event = gdk_event_make (win,
-                             key_up ? GDK_KEY_RELEASE : GDK_KEY_PRESS,
-                             TRUE);
-      if (event)
-       {
-         /* Find focused window */
-         event->key.time = now;
-         event->key.state = k->modifier_state;
-         event->key.keyval = keyval;
-         event->key.length = isprint (event->key.keyval) ? 1 : 0;
-         dummy[0] = event->key.keyval;
-         dummy[1] = 0;
-         event->key.string = event->key.length ? g_strdup(dummy) : NULL;
-       }
-    }
-
-  input_activity ();
-
-  return TRUE;
-}
-
-static gboolean
-handle_xlate_keyboard_input (GIOChannel *gioc,
-                            GIOCondition cond,
-                            gpointer data)
-{
-  guchar buf[128];
-  int i, n;
-  Keyboard *k = data;
-  guint32 now;
-
-  n = read (k->fd, buf, sizeof(buf));
-  if (n <= 0)
-    g_error ("Nothing from keyboard!");
-
-  /* Now turn this into a keyboard event */
-  now = gdk_fb_get_time ();
-
-  for (i = 0; i < n; i++)
-    {
-      GdkEvent *event;
-      GdkWindow *win;
-      char dummy[2];
-      guint keyval;
-
-      keyval = buf[i];
-
-      switch (keyval) {
-      case '\n':
-       keyval = GDK_Return;
-       break;
-      case '\t':
-       keyval = GDK_Tab;
-       break;
-      case 127:
-       keyval = GDK_BackSpace;
-       break;
-      case 27:
-       keyval = GDK_Escape;
-       break;
-      }
-
-      win = gdk_window_find_focus ();
-      
-      /* Send key down: */
-      event = gdk_event_make (win, GDK_KEY_PRESS, TRUE);
-      if (event)
-       {
-         /* Find focused window */
-         event->key.time = now;
-         event->key.state = k->modifier_state;
-         event->key.keyval = keyval;
-         event->key.length = isprint (event->key.keyval) ? 1 : 0;
-         dummy[0] = event->key.keyval;
-         dummy[1] = 0;
-         event->key.string = event->key.length ? g_strdup(dummy) : NULL;
-       }
-
-      /* Send key up: */
-      event = gdk_event_make (win, GDK_KEY_RELEASE, TRUE);
-      if (event)
-       {
-         /* Find focused window */
-         event->key.time = now;
-         event->key.state = k->modifier_state;
-         event->key.keyval = keyval;
-         event->key.length = isprint (event->key.keyval) ? 1 : 0;
-         dummy[0] = event->key.keyval;
-         dummy[1] = 0;
-         event->key.string = event->key.length ? g_strdup(dummy) : NULL;
-       }
-    }
-
-  input_activity ();
-
-  return TRUE;
-}
-
-
-static Keyboard *
-tty_keyboard_open (void)
-{
-  Keyboard *retval = g_new0 (Keyboard, 1);
-  GIOChannel *gioc;
-  const char cursoroff_str[] = "\033[?1;0;0c";
-  int n;
-  struct vt_stat vs;
-  char buf[32];
-  struct termios ts;
-  gboolean raw_keyboard;
-
-  retval->modifier_state = 0;
-  retval->caps_lock = 0;
-  
-  setsid();
-  retval->consfd = open ("/dev/console", O_RDWR);
-  ioctl (retval->consfd, VT_GETSTATE, &vs);
-  retval->prev_vtnum = vs.v_active;
-  g_snprintf (buf, sizeof(buf), "/dev/tty%d", retval->prev_vtnum);
-  ioctl (retval->consfd, KDSKBMODE, K_XLATE);
-
-  n = ioctl (retval->consfd, VT_OPENQRY, &retval->vtnum);
-  if (n < 0 || retval->vtnum == -1)
-    g_error("Cannot allocate VT");
-
-  ioctl (retval->consfd, VT_ACTIVATE, retval->vtnum);
-  ioctl (retval->consfd, VT_WAITACTIVE, retval->vtnum);
-
-#if 0
-  close (0);
-  close (1);
-  close (2);
-#endif
-  
-  g_snprintf (buf, sizeof(buf), "/dev/tty%d", retval->vtnum);
-  retval->fd = open (buf, O_RDWR|O_NONBLOCK);
-  if (retval->fd < 0)
-    return NULL;
-  raw_keyboard = TRUE;
-  if (ioctl (retval->fd, KDSKBMODE, K_MEDIUMRAW) < 0)
-    {
-      raw_keyboard = FALSE;
-      g_warning ("K_MEDIUMRAW failed, using broken XLATE keyboard driver");
-    }
-
-  /* Disable normal text on the console */
-  ioctl (retval->fd, KDSETMODE, KD_GRAPHICS);
-
-  /* Set controlling tty */
-  ioctl (0, TIOCNOTTY, 0);
-  ioctl (retval->fd, TIOCSCTTY, 0);
-  tcgetattr (retval->fd, &ts);
-  ts.c_cc[VTIME] = 0;
-  ts.c_cc[VMIN] = 1;
-  ts.c_lflag &= ~(ICANON|ECHO|ISIG);
-  ts.c_iflag = 0;
-  tcsetattr (retval->fd, TCSAFLUSH, &ts);
-
-  tcsetpgrp (retval->fd, getpgrp());
-
-  write (retval->fd, cursoroff_str, strlen (cursoroff_str));
-
-#if 0
-  if (retval->fd != 0)
-    dup2 (retval->fd, 0);
-  if (retval->fd != 1)
-    dup2 (retval->fd, 1);
-  if (retval->fd != 2)
-    dup2 (retval->fd, 2);
-#endif
-
-  gioc = g_io_channel_unix_new (retval->fd);
-  retval->fd_tag = g_io_add_watch (gioc,
-                                  G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-                                  (raw_keyboard) ? handle_mediumraw_keyboard_input : handle_xlate_keyboard_input,
-                                  retval);
-
-  return retval;
-}
-
-void
-gdk_beep (void)
-{
-  static int pitch = 600, duration = 100;
-  gulong arg;
-
-  if (!keyboard)
-    return;
-
-  /* Thank you XFree86 */
-  arg = ((1193190 / pitch) & 0xffff) |
-    (((unsigned long)duration) << 16);
-
-  ioctl (keyboard->fd, KDMKTONE, arg);
-}
-
-void
-keyboard_init (void)
-{
-  keyboard = tty_keyboard_open ();
-}
-
-void
-keyboard_shutdown (void)
-{
-  int tmpfd;
-
-  ioctl (keyboard->fd, KDSETMODE, KD_TEXT);
-  ioctl (keyboard->fd, KDSKBMODE, K_XLATE);
-  close (keyboard->fd);
-  g_source_remove (keyboard->fd_tag);
-
-  tmpfd = keyboard->consfd;
-  ioctl (tmpfd, VT_ACTIVATE, keyboard->prev_vtnum);
-  ioctl (tmpfd, VT_WAITACTIVE, keyboard->prev_vtnum);
-  ioctl (tmpfd, VT_DISALLOCATE, keyboard->vtnum);
-  close (tmpfd);
-
-  g_free (keyboard);
-  keyboard = NULL;
-}
-
-
index 87791852a9bcbe14a95317666f5881d6f00277d4..82ccc845d0759e1d94fb9fadfe49f17d8bd2d902 100644 (file)
@@ -277,6 +277,13 @@ gdk_input_window_destroy (GdkWindow *window)
   g_free (input_window);
 }
 
+void
+gdk_input_init (void)
+{
+  gdk_input_devices = g_list_append (NULL, gdk_core_pointer);
+  gdk_input_ignore_core = FALSE;
+}
+
 void
 gdk_input_exit (void)
 {
diff --git a/gdk/linux-fb/gdkkeyboard-fb.c b/gdk/linux-fb/gdkkeyboard-fb.c
new file mode 100644 (file)
index 0000000..f2e9acc
--- /dev/null
@@ -0,0 +1,1431 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gdk/gdk.h>
+#include <gdk/gdkinternals.h>
+#include "gdkkeysyms.h"
+#include "gdkprivate-fb.h"
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/kd.h>
+#include <sys/vt.h>
+
+typedef struct _GdkFBKeyboard GdkFBKeyboard;
+typedef struct _GdkFBKeyboardDevice GdkFBKeyboardDevice;
+
+struct _GdkFBKeyboard {
+  gint fd;
+  GIOChannel *io;
+  gint io_tag;
+
+  guint modifier_state;
+  gboolean caps_lock : 1;
+
+  gint group;
+  gint level;
+  
+  GdkFBKeyboardDevice *dev;
+};
+
+struct _GdkFBKeyboardDevice {
+  char *name;
+  gboolean (*open)(GdkFBKeyboard *kb);
+  void (*close)(GdkFBKeyboard *kb);
+
+  guint    (*lookup_key)               (GdkFBKeyboard       *kb,
+                                       const GdkKeymapKey  *key);
+  gboolean (*translate_keyboard_state) (GdkFBKeyboard       *kb,
+                                       guint                hardware_keycode,
+                                       GdkModifierType      state,
+                                       gint                 group,
+                                       guint               *keyval,
+                                       gint                *effective_group,
+                                       gint                *level,
+                                       GdkModifierType     *unused_modifiers);
+  gboolean (*get_entries_for_keyval)   (GdkFBKeyboard       *kb,
+                                       guint                keyval,
+                                       GdkKeymapKey       **keys,
+                                       gint                *n_keys);
+  gboolean (*get_entries_for_keycode)  (GdkFBKeyboard       *kb,
+                                       guint                hardware_keycode,
+                                       GdkKeymapKey       **keys,
+                                       guint              **keyvals,
+                                       gint                *n_entries);
+
+  gpointer driver_data;
+};
+
+static GdkFBKeyboard *gdk_fb_keyboard = NULL;
+
+static gboolean xlate_open            (GdkFBKeyboard       *kb);
+static void     xlate_close           (GdkFBKeyboard       *kb);
+static guint    xlate_lookup          (GdkFBKeyboard       *kb,
+                                      const GdkKeymapKey  *key);
+static gboolean xlate_translate       (GdkFBKeyboard       *kb,
+                                      guint                hardware_keycode,
+                                      GdkModifierType      state,
+                                      gint                 group,
+                                      guint               *keyval,
+                                      gint                *effective_group,
+                                      gint                *level,
+                                      GdkModifierType     *unused_modifiers);
+static gboolean xlate_get_for_keyval  (GdkFBKeyboard       *kb,
+                                      guint                keyval,
+                                      GdkKeymapKey       **keys,
+                                      gint                *n_keys);
+static gboolean xlate_get_for_keycode (GdkFBKeyboard       *kb,
+                                      guint                hardware_keycode,
+                                      GdkKeymapKey       **keys,
+                                      guint              **keyvals,
+                                      gint                *n_entries);
+
+static gboolean raw_open            (GdkFBKeyboard       *kb);
+static void     raw_close           (GdkFBKeyboard       *kb);
+static guint    raw_lookup          (GdkFBKeyboard       *kb,
+                                    const GdkKeymapKey  *key);
+static gboolean raw_translate       (GdkFBKeyboard       *kb,
+                                    guint                hardware_keycode,
+                                    GdkModifierType      state,
+                                    gint                 group,
+                                    guint               *keyval,
+                                    gint                *effective_group,
+                                    gint                *level,
+                                    GdkModifierType     *unused_modifiers);
+static gboolean raw_get_for_keyval  (GdkFBKeyboard       *kb,
+                                    guint                keyval,
+                                    GdkKeymapKey       **keys,
+                                    gint                *n_keys);
+static gboolean raw_get_for_keycode (GdkFBKeyboard       *kb,
+                                    guint                hardware_keycode,
+                                    GdkKeymapKey       **keys,
+                                    guint              **keyvals,
+                                    gint                *n_entries);
+
+
+static GdkFBKeyboardDevice keyb_devs[] =
+{
+  {
+    "xlate",
+    xlate_open,
+    xlate_close,
+    xlate_lookup,
+    xlate_translate,
+    xlate_get_for_keyval,
+    xlate_get_for_keycode
+  },
+  {
+    "raw",
+    raw_open,
+    raw_close,
+    raw_lookup,
+    raw_translate,
+    raw_get_for_keyval,
+    raw_get_for_keycode
+  },
+};
+
+guint
+gdk_fb_keyboard_modifiers ()
+{
+  return gdk_fb_keyboard->modifier_state;
+}
+
+gboolean
+gdk_fb_keyboard_open (void)
+{
+  GdkFBKeyboard *keyb;
+  GdkFBKeyboardDevice *device;
+  char *keyb_type;
+  int i;
+
+  keyb = g_new0 (GdkFBKeyboard, 1);
+  keyb->fd = -1;
+  
+  keyb_type = getenv ("GDK_KEYBOARD_TYPE");
+  if (!keyb_type)
+    keyb_type = "xlate";
+
+  for (i=0;i<G_N_ELEMENTS(keyb_devs);i++)
+    {
+      if (g_strcasecmp(keyb_type, keyb_devs[i].name)==0)
+       break;
+    }
+  
+  if (i == G_N_ELEMENTS(keyb_devs))
+    {
+      g_warning ("No keyboard driver of type %s found", keyb_type);
+      return FALSE;
+    }
+
+  device = &keyb_devs[i];
+
+  keyb->dev = device;
+  
+  if (!device->open(keyb))
+    {
+      g_warning ("Keyboard driver open failed");
+      g_free (keyb);
+      return FALSE;
+    }
+
+  gdk_fb_keyboard = keyb;
+  
+  return TRUE;
+}
+
+void 
+gdk_fb_keyboard_close (void)
+{
+  gdk_fb_keyboard->dev->close(gdk_fb_keyboard);
+  g_free (gdk_fb_keyboard);
+}
+
+
+/**
+ * gdk_keymap_get_entries_for_keyval:
+ * @keymap: a #GdkKeymap, or %NULL to use the default keymap
+ * @keyval: a keyval, such as %GDK_a, %GDK_Up, %GDK_Return, etc.
+ * @keys: return location for an array of #GdkKeymapKey
+ * @n_keys: return location for number of elements in returned array
+ * 
+ * Obtains a list of keycode/group/level combinations that will
+ * generate @keyval. Groups and levels are two kinds of keyboard mode;
+ * in general, the level determines whether the top or bottom symbol
+ * on a key is used, and the group determines whether the left or
+ * right symbol is used. On US keyboards, the shift key changes the
+ * keyboard level, and there are no groups. A group switch key might
+ * convert a keyboard between Hebrew to English modes, for example.
+ * #GdkEventKey contains a %group field that indicates the active
+ * keyboard group. The level is computed from the modifier mask.
+ * The returned array should be freed
+ * with g_free().
+ *
+ * Return value: %TRUE if keys were found and returned
+ **/
+gboolean
+gdk_keymap_get_entries_for_keyval (GdkKeymap     *keymap,
+                                   guint          keyval,
+                                   GdkKeymapKey **keys,
+                                   gint          *n_keys)
+{
+  g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
+  g_return_val_if_fail (keys != NULL, FALSE);
+  g_return_val_if_fail (n_keys != NULL, FALSE);
+  g_return_val_if_fail (keyval != 0, FALSE);
+
+  return gdk_fb_keyboard->dev->get_entries_for_keyval (gdk_fb_keyboard,
+                                                      keyval,
+                                                      keys,
+                                                      n_keys);
+}
+
+/**
+ * gdk_keymap_get_entries_for_keycode:
+ * @keymap: a #GdkKeymap or %NULL to use the default keymap
+ * @hardware_keycode: a keycode
+ * @keys: return location for array of #GdkKeymapKey, or NULL
+ * @keyvals: return location for array of keyvals, or NULL
+ * @n_entries: length of @keys and @keyvals
+ *
+ * Returns the keyvals bound to @hardware_keycode.
+ * The Nth #GdkKeymapKey in @keys is bound to the Nth
+ * keyval in @keyvals. Free the returned arrays with g_free().
+ * When a keycode is pressed by the user, the keyval from
+ * this list of entries is selected by considering the effective
+ * keyboard group and level. See gdk_keymap_translate_keyboard_state().
+ *
+ * Returns: %TRUE if there were any entries
+ **/
+gboolean
+gdk_keymap_get_entries_for_keycode (GdkKeymap     *keymap,
+                                    guint          hardware_keycode,
+                                    GdkKeymapKey **keys,
+                                    guint        **keyvals,
+                                    gint          *n_entries)
+{
+  g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
+  g_return_val_if_fail (n_entries != NULL, FALSE);
+  
+  return gdk_fb_keyboard->dev->get_entries_for_keycode (gdk_fb_keyboard,
+                                                       hardware_keycode,
+                                                       keys,
+                                                       keyvals,
+                                                       n_entries);
+}
+
+
+/**
+ * gdk_keymap_lookup_key:
+ * @keymap: a #GdkKeymap or %NULL to use the default keymap
+ * @key: a #GdkKeymapKey with keycode, group, and level initialized
+ * 
+ * Looks up the keyval mapped to a keycode/group/level triplet.
+ * If no keyval is bound to @key, returns 0. For normal user input,
+ * you want to use gdk_keymap_translate_keyboard_state() instead of
+ * this function, since the effective group/level may not be
+ * the same as the current keyboard state.
+ * 
+ * Return value: a keyval, or 0 if none was mapped to the given @key
+ **/
+guint
+gdk_keymap_lookup_key (GdkKeymap          *keymap,
+                       const GdkKeymapKey *key)
+{
+  g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), 0);
+  g_return_val_if_fail (key != NULL, 0);
+  g_return_val_if_fail (key->group < 4, 0);
+
+  return gdk_fb_keyboard->dev->lookup_key (gdk_fb_keyboard,  key);
+}
+
+
+/**
+ * gdk_keymap_translate_keyboard_state:
+ * @keymap: a #GdkKeymap, or %NULL to use the default
+ * @hardware_keycode: a keycode
+ * @state: a modifier state 
+ * @group: active keyboard group
+ * @keyval: return location for keyval
+ * @effective_group: return location for effective group
+ * @level: return location for level
+ * @unused_modifiers: return location for modifiers that didn't affect the group or level
+ * 
+ *
+ * Translates the contents of a #GdkEventKey into a keyval, effective
+ * group, and level. Modifiers that didn't affect the translation and
+ * are thus available for application use are returned in
+ * @unused_modifiers.  See gdk_keyval_get_keys() for an explanation of
+ * groups and levels.  The @effective_group is the group that was
+ * actually used for the translation; some keys such as Enter are not
+ * affected by the active keyboard group. The @level is derived from
+ * @state. For convenience, #GdkEventKey already contains the translated
+ * keyval, so this function isn't as useful as you might think.
+ * 
+ * Return value: %TRUE if there was a keyval bound to the keycode/state/group
+ **/
+gboolean
+gdk_keymap_translate_keyboard_state (GdkKeymap       *keymap,
+                                     guint            hardware_keycode,
+                                     GdkModifierType  state,
+                                     gint             group,
+                                     guint           *keyval,
+                                     gint            *effective_group,
+                                     gint            *level,
+                                     GdkModifierType *unused_modifiers)
+{
+  g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
+  g_return_val_if_fail (group < 4, FALSE);
+
+  return gdk_fb_keyboard->dev->translate_keyboard_state (gdk_fb_keyboard,
+                                                        hardware_keycode,
+                                                        state,
+                                                        group,
+                                                        keyval,
+                                                        effective_group,
+                                                        level,
+                                                        unused_modifiers);
+}
+
+static void
+gdk_fb_handle_key (guint hw_keycode,
+                  guint keyval,
+                  guint modifier_state,
+                  guint8 group,
+                  gchar *string,
+                  gint string_length,
+                  gboolean key_up)
+{
+  GdkWindow *win;
+  GdkEvent *event;
+
+  /* handle some magic keys */
+  if (key_up &&
+      (modifier_state & (GDK_CONTROL_MASK|GDK_MOD1_MASK)))
+    {
+      if (keyval == GDK_BackSpace)
+       {
+         ioctl (gdk_display->tty_fd, KDSKBMODE, K_XLATE);
+         exit (1);
+       }
+         
+      if (keyval == GDK_Return)
+       gdk_fb_redraw_all ();
+    }
+
+  /* Ctrl-Alt Return can't be pressed in the XLATE driver,
+   * use Shift F1 instead */
+  if (key_up && (keyval == GDK_F1) && (modifier_state & GDK_SHIFT_MASK))
+    gdk_fb_redraw_all ();
+  
+  win = gdk_fb_window_find_focus ();
+  event = gdk_event_make (win,
+                         key_up ? GDK_KEY_RELEASE : GDK_KEY_PRESS,
+                         TRUE);
+  if (event)
+    {
+      event->key.state = modifier_state;
+      event->key.keyval = keyval;
+      event->key.string = string;
+      event->key.length = string_length;
+      event->key.hardware_keycode = hw_keycode;
+      event->key.group = group;
+    }
+}
+
+/******************************************************
+ ********* Device specific keyboard code **************
+ ******************************************************/
+
+
+/* XLATE keyboard driver */
+
+struct {
+  char *str;
+  guint code;
+  guint modifier;
+} xlate_codes[] =
+{
+  {"\x5b\x41", GDK_F1},
+  {"\x5b\x42", GDK_F2},
+  {"\x5b\x43", GDK_F3},
+  {"\x5b\x44", GDK_F4},
+  {"\x5b\x45", GDK_F5},
+  {"\x31\x37\x7e", GDK_F6},
+  {"\x31\x38\x7e", GDK_F7},
+  {"\x31\x39\x7e", GDK_F8},
+  {"\x32\x30\x7e", GDK_F9},
+  {"\x32\x31\x7e", GDK_F10},
+  {"\x32\x33\x7e", GDK_F11},
+  {"\x32\x34\x7e", GDK_F12},
+  
+  {"\x32\x35\x7e", GDK_F1, GDK_SHIFT_MASK},
+  {"\x32\x36\x7e", GDK_F2, GDK_SHIFT_MASK},
+  {"\x32\x38\x7e", GDK_F3, GDK_SHIFT_MASK},
+  {"\x32\x39\x7e", GDK_F4, GDK_SHIFT_MASK},
+  {"\x33\x31\x7e", GDK_F5, GDK_SHIFT_MASK},
+  {"\x33\x32\x7e", GDK_F6, GDK_SHIFT_MASK},
+  {"\x33\x33\x7e", GDK_F7, GDK_SHIFT_MASK},
+  {"\x33\x34\x7e", GDK_F8, GDK_SHIFT_MASK},
+
+  {"\x31\x7e", GDK_Home},
+  {"\x35\x7e", GDK_Page_Up},
+  {"\x34\x7e", GDK_End},
+  {"\x36\x7e", GDK_Page_Down},
+  {"\x32\x7e", GDK_Insert},
+  {"\x33\x7e", GDK_Delete},
+
+  {"\x41", GDK_Up},
+  {"\x44", GDK_Left},
+  {"\x42", GDK_Down},
+  {"\x43", GDK_Right},
+  {"\x50", GDK_Break},
+};
+
+struct {
+  guint code;
+  guint modifier;
+} xlate_chars[] =
+{
+  /* 0x00 */
+  {'@', GDK_CONTROL_MASK},
+  {'a', GDK_CONTROL_MASK},
+  {'b', GDK_CONTROL_MASK},
+  {'c', GDK_CONTROL_MASK},
+  {'d', GDK_CONTROL_MASK},
+  {'e', GDK_CONTROL_MASK},
+  {'f', GDK_CONTROL_MASK},
+  {'g', GDK_CONTROL_MASK},
+  {'h', GDK_CONTROL_MASK},
+  {GDK_Tab, 0},
+  {'j', GDK_CONTROL_MASK},
+  {'k', GDK_CONTROL_MASK},
+  {'l', GDK_CONTROL_MASK},
+  {GDK_Return, 0},
+  {'n', GDK_CONTROL_MASK},
+  {'o', GDK_CONTROL_MASK},
+  /* 0x10 */
+  {'p', GDK_CONTROL_MASK},
+  {'q', GDK_CONTROL_MASK},
+  {'r', GDK_CONTROL_MASK},
+  {'s', GDK_CONTROL_MASK},
+  {'t', GDK_CONTROL_MASK},
+  {'u', GDK_CONTROL_MASK},
+  {'v', GDK_CONTROL_MASK},
+  {'w', GDK_CONTROL_MASK},
+  {'x', GDK_CONTROL_MASK},
+  {'y', GDK_CONTROL_MASK},
+  {'z', GDK_CONTROL_MASK},
+  {GDK_Escape, 0},
+  {'\\', GDK_CONTROL_MASK},
+  {']', GDK_CONTROL_MASK},
+  {'^', GDK_CONTROL_MASK},
+  {'_', GDK_CONTROL_MASK},
+  /* 0x20 */
+  {GDK_space, 0},
+  {'!', 0},
+  {'"', 0},
+  {'#', 0},
+  {'$', 0},
+  {'%', 0},
+  {'&', 0},
+  {'\'', 0},
+  {'(', 0},
+  {')', 0},
+  {'*', 0},
+  {'+', 0},
+  {',', 0},
+  {'-', 0},
+  {'.', 0},
+  {'/', 0},
+  /* 0x30 */
+  {'0', 0},
+  {'1', 0},
+  {'2', 0},
+  {'3', 0},
+  {'4', 0},
+  {'5', 0},
+  {'6', 0},
+  {'7', 0},
+  {'8', 0},
+  {'9', 0},
+  {':', 0},
+  {';', 0},
+  {'<', 0},
+  {'=', 0},
+  {'>', 0},
+  {'?', 0},
+  /* 0x40 */
+  {'@', 0},
+  {'A', 0},
+  {'B', 0},
+  {'C', 0},
+  {'D', 0},
+  {'E', 0},
+  {'F', 0},
+  {'G', 0},
+  {'H', 0},
+  {'I', 0},
+  {'J', 0},
+  {'K', 0},
+  {'L', 0},
+  {'M', 0},
+  {'N', 0},
+  {'O', 0},
+  /* 0x50 */
+  {'P', 0},
+  {'Q', 0},
+  {'R', 0},
+  {'S', 0},
+  {'T', 0},
+  {'U', 0},
+  {'V', 0},
+  {'W', 0},
+  {'X', 0},
+  {'Y', 0},
+  {'Z', 0},
+  {'[', 0},
+  {'\\', 0},
+  {']', 0},
+  {'^', 0},
+  {'_', 0},
+  /* 0x60 */
+  {'`', 0},
+  {'a', 0},
+  {'b', 0},
+  {'c', 0},
+  {'d', 0},
+  {'e', 0},
+  {'f', 0},
+  {'g', 0},
+  {'h', 0},
+  {'i', 0},
+  {'j', 0},
+  {'k', 0},
+  {'l', 0},
+  {'m', 0},
+  {'n', 0},
+  {'o', 0},
+  /* 0x70 */
+  {'p', 0},
+  {'q', 0},
+  {'r', 0},
+  {'s', 0},
+  {'t', 0},
+  {'u', 0},
+  {'v', 0},
+  {'w', 0},
+  {'x', 0},
+  {'y', 0},
+  {'z', 0},
+  {'{', 0},
+  {'|', 0},
+  {'}', 0},
+  {'~', 0},
+  {GDK_BackSpace, 0},
+  /* 0x80 */
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  /* 0x90 */
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  /* 0xA0 */
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  /* 0xB0 */
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  /* 0xC0 */
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  /* 0xD0 */
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  /* 0xE0 */
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  /* 0xF0 */
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+  {0, 0},
+};
+
+static gboolean
+iscode (char *code, char *str, int str_max)
+{
+  int i;
+
+  for (i=0;code[i] && (i<str_max);i++)
+    {
+      if (code[i] != str[i])
+       return FALSE;
+    }
+  return (code[i] == 0);
+}
+
+static gboolean
+xlate_io (GIOChannel *gioc,
+         GIOCondition cond,
+         gpointer data)
+{
+  GdkFBKeyboard *keyb = (GdkFBKeyboard *)data;
+  guchar buf[128];
+  guint keycode;
+  guint modifier;
+  gboolean handled;
+  int i, n, j;
+  int left;
+  
+  n = read (keyb->fd, buf, sizeof(buf));
+  if (n <= 0)
+    g_error ("Nothing from keyboard!");
+
+  for (i=0;i<n;i++)
+    {
+      handled = FALSE;
+      modifier = 0;
+      if ((buf[i] == 27) && (i+1 != n)) /* Escape */
+       {
+         /* Esc is not the last char in buffer, interpret as code sequence */
+         if (buf[i+1] == '[')
+           {
+             i += 2;
+             left = n-i;
+             if (left <= 0)
+               return TRUE;
+
+             for (j=0;j<G_N_ELEMENTS (xlate_codes);j++)
+               {
+                 if (iscode (xlate_codes[j].str, &buf[i], left))
+                   {
+                     gdk_fb_handle_key (xlate_codes[j].code,
+                                        xlate_codes[j].code,
+                                        xlate_codes[j].modifier,
+                                        0,
+                                        NULL,
+                                        0,
+                                        FALSE);
+                     gdk_fb_handle_key (xlate_codes[j].code,
+                                        xlate_codes[j].code,
+                                        xlate_codes[j].modifier,
+                                        0,
+                                        NULL,
+                                        0,
+                                        TRUE);
+                     i += strlen (xlate_codes[j].str);
+                     handled = TRUE;
+                     break;
+                   }
+               }
+           }
+         else
+           {
+             /* Alt-key */
+             modifier |= GDK_MOD1_MASK;
+             i++;
+           }
+       }
+      if (!handled)
+       {
+         char dummy[2];
+         gint len;
+         
+         keycode = xlate_chars[buf[i]].code;
+         if (keycode == 0)
+           keycode = buf[i];
+         modifier |= xlate_chars[buf[i]].modifier;
+         
+         dummy[0] = keycode;
+         dummy[1] = 0;
+
+         len = isprint (keycode) ? 1 : 0;
+         gdk_fb_handle_key (keycode,
+                            keycode,
+                            modifier,
+                            0,
+                            (len)?g_strdup(dummy) : NULL,
+                            len,
+                            FALSE);
+         gdk_fb_handle_key (keycode,
+                            keycode,
+                            modifier,
+                            0,
+                            (len)?g_strdup(dummy) : NULL,
+                            len,
+                            TRUE);
+         i++;
+       }
+    }
+  return TRUE;
+}
+
+static gboolean
+xlate_open (GdkFBKeyboard *kb)
+{
+  const char cursoroff_str[] = "\033[?1;0;0c";
+  struct termios ts;
+  
+  tcgetattr (gdk_display->tty_fd, &ts);
+  ts.c_cc[VTIME] = 0;
+  ts.c_cc[VMIN] = 1;
+  ts.c_lflag &= ~(ICANON|ECHO|ISIG);
+  ts.c_iflag = 0;
+  tcsetattr (gdk_display->tty_fd, TCSAFLUSH, &ts);
+
+  tcsetpgrp (gdk_display->tty_fd, getpgrp());
+
+  write (gdk_display->tty_fd, cursoroff_str, strlen (cursoroff_str));
+  
+  ioctl (gdk_display->tty_fd, KDSKBMODE, K_XLATE);
+
+  kb->fd = gdk_display->tty_fd;
+  kb->io = g_io_channel_unix_new (kb->fd);
+  kb->io_tag = g_io_add_watch (kb->io,
+                              G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+                              xlate_io,
+                              kb);
+  
+  return TRUE;
+}
+
+static void
+xlate_close (GdkFBKeyboard *kb)
+{
+  struct termios ts;
+  const char cursoron_str[] = "\033c";
+
+  write (gdk_display->tty_fd, cursoron_str, strlen (cursoron_str));
+
+  tcgetattr (gdk_display->tty_fd, &ts);
+  ts.c_lflag |= (ICANON|ECHO|ISIG);
+  tcsetattr (gdk_display->tty_fd, TCSAFLUSH, &ts);
+  
+  g_source_remove (kb->io_tag);
+  g_io_channel_unref (kb->io);
+  /* don't close kb->fd, it is the tty from gdk_display */
+  g_free (kb);
+}
+
+static guint
+xlate_lookup (GdkFBKeyboard       *kb,
+             const GdkKeymapKey  *key)
+{
+  g_warning ("xlate_lookup() NIY");
+  return FALSE;
+}
+
+static gboolean
+xlate_translate (GdkFBKeyboard       *kb,
+                guint                hardware_keycode,
+                GdkModifierType      state,
+                gint                 group,
+                guint               *keyval,
+                gint                *effective_group,
+                gint                *level,
+                GdkModifierType     *unused_modifiers)
+{
+  g_warning ("xlate_translate() NIY");
+  return FALSE;
+}
+
+static gboolean
+xlate_get_for_keyval (GdkFBKeyboard       *kb,
+                     guint                keyval,
+                     GdkKeymapKey       **keys,
+                     gint                *n_keys)
+{
+  g_warning ("xlate_get_for_keyval() NIY");
+  return FALSE;
+}
+
+static gboolean
+xlate_get_for_keycode (GdkFBKeyboard       *kb,
+                      guint                hardware_keycode,
+                      GdkKeymapKey       **keys,
+                      guint              **keyvals,
+                      gint                *n_entries)
+{
+  g_warning ("xlate_get_for_keycode() NIY");
+  return FALSE;
+}
+
+/* Raw keyboard support */
+
+static const guint trans_table[256][3] = {
+  /* 0x00 */
+  {0, 0, 0},
+  {GDK_Escape, 0, 0},
+  {'1', '!', 0},
+  {'2', '@', 0},
+  {'3', '#', 0},
+  {'4', '$', 0},
+  {'5', '%', 0},
+  {'6', '^', 0},
+  {'7', '&', 0},
+  {'8', '*', 0},
+  {'9', '(', 0},
+  {'0', ')', 0},
+  {'-', '_', 0},
+  {'=', '+', 0},
+  {GDK_BackSpace, 0, 0},
+  {GDK_Tab, 0, 0},
+
+  /* 0x10 */
+  {'q', 'Q', 0},
+  {'w', 'W', 0},
+  {'e', 'E', 0},
+  {'r', 'R', 0},
+  {'t', 'T', 0},
+  {'y', 'Y', 0},
+  {'u', 'U', 0},
+  {'i', 'I', 0},
+  {'o', 'O', 0},
+  {'p', 'P', 0},
+  {'[', '{', 0},
+  {']', '}', 0},
+  {GDK_Return, 0, 0},
+  {GDK_Control_L, 0, 0}, /* mod */
+  {'a', 'A', 0},
+  {'s', 'S', 0},
+
+       /* 0x20 */
+  {'d', 'D', 0},
+  {'f', 'F', 0},
+  {'g', 'G', 0},
+  {'h', 'H', 0},
+  {'j', 'J', 0},
+  {'k', 'K', 0},
+  {'l', 'L', 0},
+  {';', ':', 0},
+  {'\'', '"', 0},
+  {'`', '~', 0},
+  {GDK_Shift_L, 0, 0}, /* mod */
+  {'\\', 0, 0},
+  {'z', 0, 0},
+  {'x', 0, 0},
+  {'c', 0, 0},
+
+  {'v', 'V', 0},
+
+       /* 0x30 */
+  {'b', 'B', 0},
+  {'n', 'N', 0},
+  {'m', 'M', 0},
+  {',', 0, 0},
+  {'.', 0, 0},
+  {'/', 0, 0},
+  {GDK_Shift_R, 0, 0}, /* mod */
+  {GDK_KP_Multiply, 0, 0},
+  {0, 0, 0},
+  {GDK_space, 0, 0},
+  {0, 0, 0},
+  {GDK_F1, 0, 0},
+  {GDK_F2, 0, 0},
+  {GDK_F3, 0, 0},
+  {GDK_F4, 0, 0},
+  {GDK_F5, 0, 0},
+
+       /* 0x40 */
+  {GDK_F6, 0, 0},
+  {GDK_F7, 0, 0},
+  {GDK_F8, 0, 0},
+  {GDK_F9, 0, 0},
+  {GDK_F10, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {'7', 0, 0},
+  {'8', 0, 0},
+  {'9', 0, 0},
+  {'-', 0, 0},
+  {'4', 0, 0},
+  {'5', 0, 0},
+  {'6', 0, 0},
+  {'+', 0, 0},
+  {'1', 0, 0},
+
+       /* 0x50 */
+  {'2', 0, 0},
+  {'3', 0, 0},
+  {'0', 0, 0},
+  {'.', 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {GDK_F11, 0, 0},
+  {GDK_F12, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0x60 */
+  {GDK_Return, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0x70 */
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0x80 */
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0x90 */
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0xA0 */
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0xB0 */
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0xC0 */
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {GDK_Up, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {GDK_Left, 0, 0},
+  {0, 0, 0},
+  {GDK_Right, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0xD0 */
+  {GDK_Down, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0xE0 */
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+
+       /* 0xF0 */
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+  {0, 0, 0},
+};
+
+static gboolean
+raw_io (GIOChannel *gioc,
+       GIOCondition cond,
+       gpointer data)
+{
+  GdkFBKeyboard *k = data;
+  guchar buf[128];
+  int i, n;
+
+  n = read (k->fd, buf, sizeof(buf));
+  if (n <= 0)
+    g_error("Nothing from keyboard!");
+
+  for (i = 0; i < n; i++)
+    {
+      guchar keycode;
+      gboolean key_up;
+      char dummy[2];
+      int len;
+      int mod;
+      guint keyval;
+
+      keycode = buf[i] & 0x7F;
+      key_up = buf[i] & 0x80;
+
+      if (keycode > G_N_ELEMENTS (trans_table))
+       {
+         g_warning ("Unknown keycode");
+         continue;
+       }
+
+      if ( (keycode == 0x1D) /* left Ctrl */
+          || (keycode == 0x9D) /* right Ctrl */
+          || (keycode == 0x38) /* left Alt */
+          || (keycode == 0xB8) /* right Alt */
+          || (keycode == 0x2A) /* left Shift */
+          || (keycode == 0x36) /* right Shift */)
+       {
+         switch (keycode)
+           {
+           case 0x1D: /* Left Ctrl */
+           case 0x9D: /* Right Ctrl */
+             if (key_up)
+               k->modifier_state &= ~GDK_CONTROL_MASK;
+             else
+               k->modifier_state |= GDK_CONTROL_MASK;
+             break;
+           case 0x38: /* Left Alt */
+           case 0xB8: /* Right Alt */
+             if (key_up)
+               k->modifier_state &= ~GDK_MOD1_MASK;
+             else
+               k->modifier_state |= GDK_MOD1_MASK;
+             break;
+           case 0x2A: /* Left Shift */
+           case 0x36: /* Right Shift */
+             if (key_up)
+               k->modifier_state &= ~GDK_SHIFT_MASK;
+             else
+               k->modifier_state |= GDK_SHIFT_MASK;
+             break;
+           }
+         continue; /* Don't generate events for modifiers */
+       }
+
+      if (keycode == 0x3A /* Caps lock */)
+       {
+         if (!key_up)
+           k->caps_lock = !k->caps_lock;
+         
+         ioctl (k->fd, KDSETLED, k->caps_lock ? LED_CAP : 0);
+         continue;
+       }
+
+      if (trans_table[keycode][0] >= GDK_F1 &&
+         trans_table[keycode][0] <= GDK_F35 &&
+         (k->modifier_state & GDK_MOD1_MASK))
+       {
+         if (key_up) /* Only switch on release */
+           {
+             gint vtnum = trans_table[keycode][0] - GDK_F1 + 1;
+
+             /* Do the whole funky VT switch thing */
+             ioctl (gdk_display->console_fd, VT_ACTIVATE, vtnum);
+             ioctl (gdk_display->console_fd, VT_WAITACTIVE, gdk_display->vt);
+             gdk_fb_redraw_all ();
+           }
+
+         continue;
+       }
+
+      keyval = 0;
+      mod = 0;
+      if (k->modifier_state & GDK_CONTROL_MASK)
+       mod = 2;
+      else if (k->modifier_state & GDK_SHIFT_MASK)
+       mod = 1;
+      do {
+       keyval = trans_table[keycode][mod--];
+      } while (!keyval && (mod >= 0));
+
+      if (k->caps_lock && (keyval >= 'a') && (keyval <= 'z'))
+       keyval = toupper (keyval);
+
+      if (!keyval)
+       continue;
+
+      len = isprint (keyval) ? 1 : 0;
+      dummy[0] = keyval;
+      dummy[1] = 0;
+
+      gdk_fb_handle_key (keycode,
+                        keyval,
+                        k->modifier_state,
+                        0,
+                        (len)?g_strdup(dummy):NULL,
+                        len,
+                        key_up);
+    }
+
+  return TRUE;
+}
+
+static gboolean
+raw_open (GdkFBKeyboard *kb)
+{
+  const char cursoroff_str[] = "\033[?1;0;0c";
+  struct termios ts;
+  
+  tcgetattr (gdk_display->tty_fd, &ts);
+  ts.c_cc[VTIME] = 0;
+  ts.c_cc[VMIN] = 1;
+  ts.c_lflag &= ~(ICANON|ECHO|ISIG);
+  ts.c_iflag = 0;
+  tcsetattr (gdk_display->tty_fd, TCSAFLUSH, &ts);
+
+  tcsetpgrp (gdk_display->tty_fd, getpgrp());
+
+  write (gdk_display->tty_fd, cursoroff_str, strlen (cursoroff_str));
+  
+  if (ioctl (gdk_display->tty_fd, KDSKBMODE, K_MEDIUMRAW) < 0)
+    {
+      g_warning ("setting tty to K_MEDIUMRAW failed");
+      return FALSE;
+    }
+
+  kb->fd = gdk_display->tty_fd;
+  kb->io = g_io_channel_unix_new (kb->fd);
+  kb->io_tag = g_io_add_watch (kb->io,
+                              G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+                              raw_io,
+                              kb);
+  
+  return TRUE;
+}
+
+static void
+raw_close (GdkFBKeyboard *kb)
+{
+  struct termios ts;
+  const char cursoron_str[] = "\033c";
+
+  write (gdk_display->tty_fd, cursoron_str, strlen (cursoron_str));
+
+  tcgetattr (gdk_display->tty_fd, &ts);
+  ts.c_lflag |= (ICANON|ECHO|ISIG);
+  tcsetattr (gdk_display->tty_fd, TCSAFLUSH, &ts);
+  
+  ioctl (gdk_display->tty_fd, KDSKBMODE, K_XLATE);
+
+  g_source_remove (kb->io_tag);
+  g_io_channel_unref (kb->io);
+  /* don't close kb->fd, it is the tty from gdk_display */
+  g_free (kb);
+}
+
+static guint
+raw_lookup (GdkFBKeyboard       *kb,
+             const GdkKeymapKey  *key)
+{
+  g_warning ("raw_lookup() NIY");
+  return FALSE;
+}
+
+static gboolean
+raw_translate (GdkFBKeyboard       *kb,
+                guint                hardware_keycode,
+                GdkModifierType      state,
+                gint                 group,
+                guint               *keyval,
+                gint                *effective_group,
+                gint                *level,
+                GdkModifierType     *unused_modifiers)
+{
+  g_warning ("raw_translate() NIY");
+  return FALSE;
+}
+
+static gboolean
+raw_get_for_keyval (GdkFBKeyboard       *kb,
+                     guint                keyval,
+                     GdkKeymapKey       **keys,
+                     gint                *n_keys)
+{
+  g_warning ("raw_get_for_keyval() NIY");
+  return FALSE;
+}
+
+static gboolean
+raw_get_for_keycode (GdkFBKeyboard       *kb,
+                      guint                hardware_keycode,
+                      GdkKeymapKey       **keys,
+                      guint              **keyvals,
+                      gint                *n_entries)
+{
+  g_warning ("raw_get_for_keycode() NIY");
+  return FALSE;
+}
index c8f8d12a9e8ce76af1838f8a9748bf3d4f91a549..97f9c836a801886be0918c6c7693e8411f4adde5 100644 (file)
@@ -35,6 +35,8 @@
 #include <time.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/vt.h>
+#include <sys/kd.h>
 
 #include "gdk.h"
 
@@ -308,7 +310,7 @@ fb_modes_parse_mode (GScanner *scanner,
 
   if (strcmp (modename, specified_modename)== 0) {
     if (!found_geometry)
-      g_warning ("Geometry not specified\n");
+      g_warning ("Geometry not specified");
 
     if (found_geometry)
       {
@@ -320,7 +322,7 @@ fb_modes_parse_mode (GScanner *scanner,
       }
     
     if (!found_timings)
-      g_warning ("Timing not specified\n");
+      g_warning ("Timing not specified");
     
     if (found_timings)
       {
@@ -371,7 +373,7 @@ gdk_fb_setup_mode_from_name (struct fb_var_screeninfo *modeinfo,
   fd = open (filename, O_RDONLY);
   if (fd < 0)
     {
-      g_warning ("Cannot read %s\n", filename);
+      g_warning ("Cannot read %s", filename);
       return retval;
     }
   
@@ -390,7 +392,7 @@ gdk_fb_setup_mode_from_name (struct fb_var_screeninfo *modeinfo,
     result = fb_modes_parse_mode (scanner, modeinfo, modename);
       
     if (result < 0) {
-      g_warning ("parse error in %s at line %d\n", filename, scanner->line);
+      g_warning ("parse error in %s at line %d", filename, scanner->line);
       break;
     }
     if (result > 0)
@@ -413,15 +415,22 @@ gdk_fb_set_mode (GdkFBDisplay *display)
 {
   char *env, *end;
   int depth, height, width;
+  gboolean changed;
   
-  if (ioctl (display->fd, FBIOGET_VSCREENINFO, &display->modeinfo) < 0)
+  if (ioctl (display->fb_fd, FBIOGET_VSCREENINFO, &display->modeinfo) < 0)
     return -1;
+
+  display->orig_modeinfo = display->modeinfo;
+
+  changed = FALSE;
   
   env = getenv ("GDK_DISPLAY_MODE");
   if (env)
     {
-      if (!gdk_fb_setup_mode_from_name (&display->modeinfo, env))
-       g_warning ("Couldn't find mode named '%s'\n", env);
+      if (gdk_fb_setup_mode_from_name (&display->modeinfo, env))
+       changed = TRUE;
+      else
+       g_warning ("Couldn't find mode named '%s'", env);
     }
 
   env = getenv ("GDK_DISPLAY_DEPTH");
@@ -429,7 +438,10 @@ gdk_fb_set_mode (GdkFBDisplay *display)
     {
       depth = strtol (env, &end, 10);
       if (env != end)
-       display->modeinfo.bits_per_pixel = depth;
+       {
+         changed = TRUE;
+         display->modeinfo.bits_per_pixel = depth;
+       }
     }
   
   env = getenv ("GDK_DISPLAY_WIDTH");
@@ -438,6 +450,7 @@ gdk_fb_set_mode (GdkFBDisplay *display)
       width = strtol (env, &end, 10);
       if (env != end)
        {
+         changed = TRUE;
          display->modeinfo.xres = width;
          display->modeinfo.xres_virtual = width;
        }
@@ -449,74 +462,163 @@ gdk_fb_set_mode (GdkFBDisplay *display)
       height = strtol (env, &end, 10);
       if (env != end)
        {
+         changed = TRUE;
          display->modeinfo.yres = height;
          display->modeinfo.yres_virtual = height;
        }
     }
 
-  if (ioctl (display->fd, FBIOPUT_VSCREENINFO, &display->modeinfo) < 0)
+  if (changed &&
+      (ioctl (display->fb_fd, FBIOPUT_VSCREENINFO, &display->modeinfo) < 0))
     {
-      g_warning ("Couldn't set specified mode\n");
+      g_warning ("Couldn't set specified mode");
       return -1;
     }
   
-  if (ioctl (display->fd, FBIOGET_FSCREENINFO, &display->sinfo) < 0)
+  if (ioctl (display->fb_fd, FBIOGET_FSCREENINFO, &display->sinfo) < 0)
     {
-      g_warning ("Error getting fixed screen info\n");
+      g_warning ("Error getting fixed screen info");
       return -1;
     }
   return 0;
 }
 
 static GdkFBDisplay *
-gdk_fb_display_new (const char *filename)
+gdk_fb_display_new ()
 {
-  int fd;
-  GdkFBDisplay *retval;
+  GdkFBDisplay *display;
+  gchar *fb_filename;
+  struct vt_stat vs;
+  int vt, n;
+  gchar *s, *send;
+  char buf[32];
 
-  fd = open (filename, O_RDWR);
-  if (fd < 0)
-    return NULL;
+  display = g_new0 (GdkFBDisplay, 1);
+
+  display->console_fd = open ("/dev/console", O_RDWR);
+  if (display->console_fd < 0)
+    {
+      g_warning ("Can't open /dev/console");
+      g_free (display);
+      return NULL;
+    }
+  
+  ioctl (display->console_fd, VT_GETSTATE, &vs);
+  display->start_vt = vs.v_active;
 
-  retval = g_new0 (GdkFBDisplay, 1);
-  retval->fd = fd;
+  vt = display->start_vt;
+  s = getenv("GDK_VT");
+  if (s)
+    {
+      if (g_strcasecmp ("new", s)==0)
+       {
+         n = ioctl (display->console_fd, VT_OPENQRY, &vt);
+         if (n < 0 || vt == -1)
+           g_error("Cannot allocate new VT");
+       }
+      else
+       {
+         vt = strtol (s, &send, 10);
+         if (s==send)
+           {
+             g_warning ("Cannot parse GDK_TTY");
+             vt = display->start_vt;
+           }
+       }
+      
+    }
+
+  display->vt = vt;
+  
+  /* Switch to the new VT */
+  if (vt != display->start_vt)
+    {
+      ioctl (display->console_fd, VT_ACTIVATE, vt);
+      ioctl (display->console_fd, VT_WAITACTIVE, vt);
+    }
+  
+  /* Open the tty */
+  g_snprintf (buf, sizeof(buf), "/dev/tty%d", vt);
+  display->tty_fd = open (buf, O_RDWR|O_NONBLOCK);
+  if (display->tty_fd < 0)
+    {
+      g_warning ("Can't open %s", buf);
+      close (display->console_fd);
+      g_free (display);
+      return NULL;
+    }
+
+  /* Set controlling tty */
+  ioctl (0, TIOCNOTTY, 0);
+  ioctl (display->tty_fd, TIOCSCTTY, 0);
+  
+  fb_filename = gdk_get_display ();
+  display->fb_fd = open (fb_filename, O_RDWR);
+  if (display->fb_fd < 0)
+    {
+      g_warning ("Can't open %s", fb_filename);
+      g_free (fb_filename);
+      close (display->tty_fd);
+      close (display->console_fd);
+      g_free (display);
+      return NULL;
+    }
+  g_free (fb_filename);
 
-  if (gdk_fb_set_mode (retval) < 0)
+  if (gdk_fb_set_mode (display) < 0)
     {
-      g_free (retval);
+      close (display->fb_fd);
+      close (display->tty_fd);
+      close (display->console_fd);
+      g_free (display);
       return NULL;
     }
 
-  ioctl (retval->fd, FBIOBLANK, 0);
+  /* Disable normal text on the console */
+  ioctl (display->fb_fd, KDSETMODE, KD_GRAPHICS);
+
+  ioctl (display->fb_fd, FBIOBLANK, 0);
 
   /* We used to use sinfo.smem_len, but that seemed to be broken in many cases */
-  retval->fbmem = mmap (NULL,
-                       retval->modeinfo.yres * retval->sinfo.line_length,
-                       PROT_READ|PROT_WRITE,
-                       MAP_SHARED,
-                       fd,
-                       0);
-  g_assert (retval->fbmem != MAP_FAILED);
-
-  if (retval->sinfo.visual == FB_VISUAL_TRUECOLOR)
+  display->fbmem = mmap (NULL,
+                        display->modeinfo.yres * display->sinfo.line_length,
+                        PROT_READ|PROT_WRITE,
+                        MAP_SHARED,
+                        display->fb_fd,
+                        0);
+  g_assert (display->fbmem != MAP_FAILED);
+
+  if (display->sinfo.visual == FB_VISUAL_TRUECOLOR)
     {
-      retval->red_byte = retval->modeinfo.red.offset >> 3;
-      retval->green_byte = retval->modeinfo.green.offset >> 3;
-      retval->blue_byte = retval->modeinfo.blue.offset >> 3;
+      display->red_byte = display->modeinfo.red.offset >> 3;
+      display->green_byte = display->modeinfo.green.offset >> 3;
+      display->blue_byte = display->modeinfo.blue.offset >> 3;
     }
 
-  return retval;
+  return display;
 }
 
 static void
-gdk_fb_display_destroy (GdkFBDisplay *fbd)
+gdk_fb_display_destroy (GdkFBDisplay *display)
 {
-  munmap (fbd->fbmem, fbd->modeinfo.yres * fbd->sinfo.line_length);
-  close (fbd->fd);
-  g_free (fbd);
-}
+  /* Restore old framebuffer mode */
+  ioctl (display->fb_fd, FBIOPUT_VSCREENINFO, &display->orig_modeinfo);
+  
+  /* Enable normal text on the console */
+  ioctl (display->fb_fd, KDSETMODE, KD_TEXT);
+  
+  munmap (display->fbmem, display->modeinfo.yres * display->sinfo.line_length);
+  close (display->fb_fd);
 
-extern void keyboard_init(void);
+  ioctl (display->console_fd, VT_ACTIVATE, display->start_vt);
+  ioctl (display->console_fd, VT_WAITACTIVE, display->start_vt);
+  if (display->vt != display->start_vt)
+    ioctl (display->console_fd, VT_DISALLOCATE, display->vt);
+  
+  close (display->tty_fd);
+  close (display->console_fd);
+  g_free (display);
+}
 
 gboolean
 _gdk_windowing_init_check (int argc, char **argv)
@@ -524,14 +626,33 @@ _gdk_windowing_init_check (int argc, char **argv)
   if (gdk_initialized)
     return TRUE;
 
-  keyboard_init ();
-  gdk_display = gdk_fb_display_new ("/dev/fb");
+  /* Create new session and become session leader */
+  setsid();
+
+  gdk_display = gdk_fb_display_new ();
 
   if (!gdk_display)
     return FALSE;
 
   gdk_fb_font_init ();
 
+  if (!gdk_fb_keyboard_open ())
+    {
+      g_warning ("Failed to initialize keyboard");
+      gdk_fb_display_destroy (gdk_display);
+      gdk_display = NULL;
+      return FALSE;
+    }
+  
+  if (!gdk_fb_mouse_open ())
+    {
+      g_warning ("Failed to initialize mouse");
+      gdk_fb_keyboard_close ();
+      gdk_fb_display_destroy (gdk_display);
+      gdk_display = NULL;
+      return FALSE;
+    }
+
   gdk_initialized = TRUE;
 
   gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
@@ -883,12 +1004,16 @@ extern void keyboard_shutdown(void);
 void
 gdk_windowing_exit (void)
 {
-  gdk_fb_display_destroy (gdk_display);
-  gdk_display = NULL;
 
+  gdk_fb_mouse_close ();
+  
+  gdk_fb_keyboard_close ();
+  
   gdk_fb_font_fini ();
 
-  keyboard_shutdown ();
+  gdk_fb_display_destroy (gdk_display);
+  
+  gdk_display = NULL;
 }
 
 gchar*
@@ -906,7 +1031,27 @@ gdk_keyval_from_name (const gchar *keyval_name)
 gchar *
 gdk_get_display(void)
 {
-  return g_strdup ("/dev/fb0");
+  gchar *s;
+
+  s = getenv ("GDK_DISPLAY");
+  if (s==0)
+    s = "/dev/fb";
+  
+  return g_strdup (s);
+}
+
+
+void
+gdk_beep (void)
+{
+  static int pitch = 600, duration = 100;
+  gulong arg;
+
+  /* Thank you XFree86 */
+  arg = ((1193190 / pitch) & 0xffff) |
+    (((unsigned long)duration) << 16);
+
+  ioctl (gdk_display->tty_fd, KDMKTONE, arg);
 }
 
 /* utils */
@@ -968,7 +1113,7 @@ gdk_event_make (GdkWindow *window,
     {
       GdkModifierType mask;
 
-      gdk_mouse_get_info (NULL, NULL, &mask);
+      gdk_fb_mouse_get_info (NULL, NULL, &mask);
 
       if (((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK)) ||
          ((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK)) ||
index 3a149a28da3a6ed9121cbb16aea829cac1e4cd54..852f6f3f6b6cc5568367786020f9e99ff20381f1 100644 (file)
@@ -1,3 +1,22 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
 #include <gdk/gdk.h>
 #include <gdk/gdkinternals.h>
 #include "gdkprivate-fb.h"
@@ -32,9 +51,9 @@ struct _GdkFBMouse {
 static GdkFBMouse *gdk_fb_mouse = NULL;
 
 void
-gdk_mouse_get_info (gint *x,
-                   gint *y,
-                   GdkModifierType *mask)
+gdk_fb_mouse_get_info (gint *x,
+                      gint *y,
+                      GdkModifierType *mask)
 {
   if (x)
     *x = gdk_fb_mouse->x;
@@ -45,7 +64,7 @@ gdk_mouse_get_info (gint *x,
       (gdk_fb_mouse->button_pressed[0]?GDK_BUTTON1_MASK:0) |
       (gdk_fb_mouse->button_pressed[1]?GDK_BUTTON2_MASK:0) |
       (gdk_fb_mouse->button_pressed[2]?GDK_BUTTON3_MASK:0) |
-      /*keyboard->modifier_state*/0; //TODO
+      gdk_fb_keyboard_modifiers ();
 }
 
 static void
@@ -90,7 +109,7 @@ handle_mouse_movement(GdkFBMouse *mouse)
   state = (mouse->button_pressed[0]?GDK_BUTTON1_MASK:0) |
     (mouse->button_pressed[1]?GDK_BUTTON2_MASK:0) |
     (mouse->button_pressed[2]?GDK_BUTTON3_MASK:0) |
-    /*keyboard->modifier_state*/0; // TODO
+    gdk_fb_keyboard_modifiers ();
 
   event = gdk_event_make (grabwin, GDK_MOTION_NOTIFY, TRUE);
   if (event)
@@ -137,7 +156,7 @@ send_button_event (GdkFBMouse *mouse,
        (mouse->button_pressed[1] ? GDK_BUTTON2_MASK : 0) |
        (mouse->button_pressed[2] ? GDK_BUTTON3_MASK : 0) |
        (1 << (button + 8)) /* badhack */ |
-       /*keyboard->modifier_state*/0; // TODO
+       gdk_fb_keyboard_modifiers ();
       event->button.device = gdk_core_pointer;
       event->button.x_root = mouse->x;
       event->button.y_root = mouse->y;
@@ -231,7 +250,7 @@ gdk_fb_mouse_open (void)
 
   mouse = g_new0 (GdkFBMouse, 1);
   mouse->fd = -1;
-  mouse_type = getenv ("GDK_MOUSETYPE");
+  mouse_type = getenv ("GDK_MOUSE_TYPE");
   if (!mouse_type)
     mouse_type = "ps2";
 
@@ -243,7 +262,7 @@ gdk_fb_mouse_open (void)
   
   if (i == G_N_ELEMENTS(mouse_devs))
     {
-      g_warning ("No mouse driver of type %s found\n", mouse_type);
+      g_warning ("No mouse driver of type %s found", mouse_type);
       return FALSE;
     }
 
@@ -256,7 +275,7 @@ gdk_fb_mouse_open (void)
 
   if (!device->open(mouse))
     {
-      g_warning ("Mouse driver open failed\n");
+      g_warning ("Mouse driver open failed");
       g_free (mouse);
       return FALSE;
     }
index 06d026ca942af73faf4999db123cb6394ff264db..c4060152009b275c15355fb7006912495d51e701 100644 (file)
@@ -123,12 +123,17 @@ typedef struct {
 
 struct _GdkFBDisplay
 {
-  int fd;
+  int tty_fd;
+  int console_fd;
+  int vt, start_vt;
+  
+  int fb_fd;
   guchar *fbmem;
   gpointer active_cmap;
   gulong mem_len;
   struct fb_fix_screeninfo sinfo;
   struct fb_var_screeninfo modeinfo;
+  struct fb_var_screeninfo orig_modeinfo;
   int red_byte, green_byte, blue_byte; /* For truecolor */
 };
 
@@ -248,22 +253,21 @@ extern GdkGC *_gdk_fb_screen_gc;
 
 GType gdk_gc_fb_get_type (void) G_GNUC_CONST;
 
-/* Routines from gdkgeometry-fb.c */
+void       _gdk_selection_window_destroyed    (GdkWindow       *window);
+void       gdk_window_invalidate_region_clear (GdkWindow       *window,
+                                              GdkRegion       *region);
+void       gdk_window_invalidate_rect_clear   (GdkWindow       *window,
+                                              GdkRectangle    *rect);
+void       gdk_fb_window_send_crossing_events (GdkWindow       *dest,
+                                              GdkCrossingMode  mode);
+void       gdk_fb_window_move_resize          (GdkWindow       *window,
+                                              gint             x,
+                                              gint             y,
+                                              gint             width,
+                                              gint             height,
+                                              gboolean         send_expose_events);
+GdkWindow *gdk_fb_window_find_focus           (void);
 
-void      _gdk_window_init_position          (GdkWindow       *window);
-void      _gdk_selection_window_destroyed    (GdkWindow       *window);
-void      _gdk_window_move_resize_child      (GdkWindow       *window,
-                                             gint             x,
-                                             gint             y,
-                                             gint             width,
-                                             gint             height);
-void      _gdk_window_process_expose         (GdkWindow       *window,
-                                             gulong           serial,
-                                             GdkRectangle    *area);
-void      gdk_window_invalidate_region_clear (GdkWindow       *window,
-                                             GdkRegion       *region);
-void      gdk_window_invalidate_rect_clear   (GdkWindow       *window,
-                                             GdkRectangle    *rect);
 
 GdkGC *   _gdk_fb_gc_new                     (GdkDrawable     *drawable,
                                              GdkGCValues     *values,
@@ -386,14 +390,14 @@ void gdk_fb_cursor_hide(void);
 void gdk_fb_redraw_all(void);
 void gdk_fb_cursor_move (gint x, gint y, GdkWindow *in_window);
 
-void gdk_fb_window_send_crossing_events (GdkWindow *dest,
-                                        GdkCrossingMode mode);
-
-gboolean gdk_fb_mouse_open  (void);
-void     gdk_fb_mouse_close (void);
-void     gdk_mouse_get_info (gint *x, 
-                            gint *y, 
-                            GdkModifierType *mask);
+guint gdk_fb_keyboard_modifiers (void);
+gboolean gdk_fb_keyboard_open  (void);
+void     gdk_fb_keyboard_close (void);
+gboolean gdk_fb_mouse_open     (void);
+void     gdk_fb_mouse_close    (void);
+void     gdk_fb_mouse_get_info (gint            *x,
+                               gint            *y,
+                               GdkModifierType *mask);
 
 
 #define PANGO_TYPE_FB_FONT              (pango_fb_font_get_type ())
@@ -421,13 +425,6 @@ GType             pango_fb_font_get_type       (void) G_GNUC_CONST;
 PangoFBGlyphInfo *pango_fb_font_get_glyph_info (PangoFont  *font,
                                                PangoGlyph  glyph);
 
-void gdk_fb_window_move_resize (GdkWindow *window,
-                               gint       x,
-                               gint       y,
-                               gint       width,
-                               gint       height,
-                               gboolean   send_expose_events);
-
 extern void CM(void); /* Check for general mem corruption */
 extern void RP(GdkDrawable *drawable); /* Same, for pixmaps */
 
index 0d03563a8e7892a16d342f8c55bab3cb30907890..8b5a085bac2bdd8bfee1e2156683c80b0af356c3 100644 (file)
@@ -440,6 +440,28 @@ gdk_fb_redraw_all (void)
   gdk_window_process_all_updates ();
 }
 
+
+/* Focus follows pointer */
+GdkWindow *
+gdk_fb_window_find_focus (void)
+{
+  if (_gdk_fb_keyboard_grab_window)
+    return _gdk_fb_keyboard_grab_window;
+  else if (gdk_fb_window_containing_pointer)
+    {
+      GdkWindowObject *priv = (GdkWindowObject *)gdk_fb_window_containing_pointer;
+      while (priv != (GdkWindowObject *)gdk_parent_root)
+       {
+         if ((priv->parent == (GdkWindowObject *)gdk_parent_root) && priv->mapped)
+           return (GdkWindow *)priv;
+         priv = priv->parent;
+       }
+    }
+  return gdk_parent_root;
+}
+
+
 static GdkWindow *
 gdk_fb_find_common_ancestor (GdkWindow *win1,
                             GdkWindow *win2)
@@ -513,7 +535,7 @@ gdk_fb_window_send_crossing_events (GdkWindow *dest,
   if (a==b)
     return;
 
-  gdk_mouse_get_info (&x, &y, &my_mask);
+  gdk_fb_mouse_get_info (&x, &y, &my_mask);
 
   c = gdk_fb_find_common_ancestor (a, b);
 
@@ -1407,7 +1429,7 @@ gdk_window_get_pointer (GdkWindow       *window,
     window = gdk_parent_root;
   
   gdk_window_get_root_origin (window, &x_int, &y_int);
-  gdk_mouse_get_info (&winx, &winy, &my_mask);
+  gdk_fb_mouse_get_info (&winx, &winy, &my_mask);
 
   winx -= x_int;
   winy -= y_int;